﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace FilesMerger2._0
{
    public class Comparer
    {
        public static CompareResult CompareTables(DataTable first, DataTable second, List<String> actualColumns)
        {
            ExecuteAndCompareForm.Log.DebugFormat("First table columns: " + first.Columns.Cast<DataColumn>().Aggregate(String.Empty, (r, x) => r += x + "; "));
            ExecuteAndCompareForm.Log.DebugFormat("Second table columns: " + second.Columns.Cast<DataColumn>().Aggregate(String.Empty, (r, x) => r += x + "; "));
            ExecuteAndCompareForm.Log.DebugFormat("Comparing columns: " + actualColumns.Aggregate(String.Empty, (r, x) => r += x + "; "));
            var result = new CompareResult();
            if (first.Rows.Count == second.Rows.Count)
            {
                if (
                    actualColumns.Any(
                        actualColumn =>
                        (!(first.Columns.Contains(actualColumn) && second.Columns.Contains(actualColumn))) &&
                        (first.Columns.Contains(actualColumn) || second.Columns.Contains(actualColumn))))
                {
                    result.Result = DiffType.ColumnMismatch;
                    FillEqualityList(first, second, result);
                    return result;
                }

                for (var i = 0; i < first.Rows.Count; i++)
                {
                    ExecuteAndCompareForm.Log.DebugFormat("Comparing row: " + i);
                    var firstRow = first.Rows[i];
                    var secondRow = second.Rows[i];
                    var rowsEqual = true;
                    foreach (var actualColumn in actualColumns)
                    {
                        ExecuteAndCompareForm.Log.DebugFormat("Comparing columns: {0}", actualColumn);
                        var firstColumnName = String.Empty;
                        var secondColumnName = String.Empty;
                        if (actualColumn.Split('=').Length > 1)
                        {
                            ExecuteAndCompareForm.Log.DebugFormat("1");
                            firstColumnName = actualColumn.Split('=')[0].Trim();
                            secondColumnName = actualColumn.Split('=')[1].Trim();
                        }
                        else
                        {
                            ExecuteAndCompareForm.Log.DebugFormat("2");
                            firstColumnName = actualColumn.Trim();
                            secondColumnName = actualColumn.Trim();
                        }

                        if (first.Columns.Contains(firstColumnName) && second.Columns.Contains(secondColumnName))
                        {
                            ExecuteAndCompareForm.Log.DebugFormat("3");
                            var firstValue = String.Empty;
                            var secondValue = String.Empty;

                            firstValue = firstRow[firstColumnName].ToString();
                            secondValue = secondRow[secondColumnName].ToString();

                            if (firstValue != secondValue)
                            {
                                Decimal decimalFirst;
                                Decimal decimalSecond;
                                if (Decimal.TryParse(firstValue, out decimalFirst) && Decimal.TryParse(secondValue, out decimalSecond))
                                {
                                    if(decimalFirst == decimalSecond)
                                        continue;
                                }

                                result.Result = DiffType.Different;
                                rowsEqual = false;
                            }
                        }
                    }
                    ExecuteAndCompareForm.Log.DebugFormat("rows equal: {0}", rowsEqual);
                    result.EqualityList.Add(rowsEqual);

                }
            }
            else
            {
                result.Result = DiffType.RowCountMismatch;
                FillEqualityList(first, second, result);
            }
            return result;

        }

        private static void FillEqualityList(DataTable first, DataTable second, CompareResult result)
        {
            for (var i = 0; i < Math.Max(first.Rows.Count, second.Rows.Count); i++)
            {
                result.EqualityList.Add(false);
            }
        }
    }

    public enum DiffType
    {
        Equal,
        Different,
        RowCountMismatch,
        ColumnMismatch
    }

    public class CompareResult
    {
        public List<Boolean> EqualityList;
        public DiffType Result;

        public CompareResult()
        {
            EqualityList = new List<Boolean>();
        }
    }
}
